/*
 * @Author: your name
 * @Date: 2022-02-20 07:55:00
 * @LastEditTime: 2022-02-20 16:27:51
 * @Descripttion: 自动弹窗自动消失基类。
 */
#ifndef AUTO_DISPLAY_H
#define AUTO_DISPLAY_H
#include "common.h"
#include "page_handle.h"
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
/**
 * @brief
 * 数据结构基类。
 */
class AutoDisplayMessage {
public:
    AutoDisplayMessage()
    {
        keepTime = 3000;
    }
    virtual ~AutoDisplayMessage() = default;
    /**
     * @brief Get the Page Name object
     * 打开的界面名称由派生类指定。
     * @return std::string
     */
    // virtual std::string GetPageName() { return ""; }
    /**
     * @brief 
     * 停留时间，单位ms，默认3000
     */
    unsigned int keepTime;
};
class AutoDisplay : public std::enable_shared_from_this<AutoDisplay> {
public:
    AutoDisplay();
    virtual ~AutoDisplay() = default;
    void Display(std::shared_ptr<AutoDisplayMessage> msg, bool immediately = true);
    /**
     * @brief
     * 打开窗口。
     * @param msg 窗口消息。
     * @param immediately 是否立即刷新数据。
     */
    void OpenPage(std::shared_ptr<AutoDisplayMessage> msg, bool immediately);
    void AddMessage(std::shared_ptr<AutoDisplayMessage> msg);
    bool GetOneMessage(std::shared_ptr<AutoDisplayMessage>& msg);
    bool GetOneMessageWithoutDelete(std::shared_ptr<AutoDisplayMessage>& msg);
    PageHandle* GetPage();
    void SetPage(PageHandle* window);
    void Displaying();
    void StopDisplay();
    void StopDisplayingClosePage();
    /**
     * @brief 
     * 刷新覆盖当前内容
     */
    void TipsDisplayingRightNow(const std::shared_ptr<AutoDisplayMessage>& msg);
    /**
     * @brief 
     * 显示一条数据。由派生类继承重写。
     */
    virtual void DisplayOneMessage(std::shared_ptr<AutoDisplayMessage> msg) { }

public:
    std::string mPageName;
    std::unique_ptr<PageHandle> page;

private:
    std::mutex m_mutex;
    std::list<std::shared_ptr<AutoDisplayMessage>> mMessageQueue;
    /**
     * @brief
     * keepTime 当前内容的停留时间，用于覆盖刷新时重置停留时间
     */
    unsigned int keepTime;
    unsigned int sleepTime;
    bool keepWorking;
    /**
     * @brief
     * 打开窗口回调函数。
     */
    void (*openPageCallback)(void*);
};
#endif